#include <boost/asio.hpp>
#include <iostream>
#include <string>

using boost::asio::ip::tcp;

class Session : public std::enable_shared_from_this<Session> {
public:
  Session(tcp::socket socket) : socket_(std::move(socket)) {}

  void start() { read_request(); }

private:
  void read_request() {
    memset(data_, 0, sizeof(char) * max_length);
    auto self(shared_from_this());
    socket_.async_read_some(
        boost::asio::buffer(data_, max_length),
        [this, self](boost::system::error_code ec, std::size_t length) {
          if (!ec) {
            write_response(length);
          } else {
            socket_.close();
          }
        });
  }

  void write_response(std::size_t length) {
    std::cout << "get data: " << data_ << std::endl;
    response_ = std::string(data_, length) + " from server";
    auto self(shared_from_this());
    boost::asio::async_write(
        socket_, boost::asio::buffer(response_),
        [this, self](boost::system::error_code ec, std::size_t /*length*/) {
          if (!ec) {
            read_request(); // 为了简单，这里直接读取下一个请求，实际应用中可能需要更复杂的逻辑
          } else {
            socket_.close();
          }
        });
  }

  tcp::socket socket_;
  enum { max_length = 1024 };
  char data_[max_length];
  std::string response_;
};

class Server {
public:
  Server(boost::asio::io_context &io_context, const tcp::endpoint &endpoint)
      : acceptor_(io_context, endpoint) {
    start_accept();
  }

private:
  void start_accept() {
    acceptor_.async_accept(
        [this](boost::system::error_code ec, tcp::socket socket) {
          if (!ec) {
            std::make_shared<Session>(std::move(socket))->start();
          }

          start_accept(); // 接受下一个连接
        });
  }

  tcp::acceptor acceptor_;
};

int main() {
  try {
    boost::asio::io_context io_context;

    tcp::endpoint endpoint(tcp::v4(), 6688); // 设置监听端口为12345
    Server s(io_context, endpoint);

    io_context.run();
  } catch (std::exception &e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}